<?php
/*
 * @Author: 哲学家乔布斯 <wuyangii@qq.com>
 * @Date: 2022-11-01 21:49:03
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2022-11-01 21:55:26
 * @Descripttion:芯烨小票打印机
 */

namespace app\common\controller;

use think\Controller;

use app\common\controller\util\NoteFormatter;

class HyPrinter extends controller
{
    private $user = "wuyangii@qq.com";
    private $UserKey = "eb6dcc74b0df462fbd6bbf6f8b72b286";
    private $code_msg = [
        '0' => '成功',
        '-1' => '请求头错误',
        '-2' => '参数不合法',
        '-3' => '成功',
        '-4' => '成功',
        '1001' => '打印机编号和用户不匹配',
        '1002' => '打印机未注册',
        '1003' => '打印机不在线',
        '1004' => '添加订单失败',
        '1005' => '未找到订单信息',
        '1006' => '订单日期格式或大小不正确',
        '1007' => '打印内容不能超过12K',
        '1008' => '用户修改打印机记录失败',
        '1009' => '用户添加打印机时，打印机编号或名称不能为空',
        '1010' => '打印机设备编号无效',
        '1011' => '打印机已存在，若当前开放平台无法查询到打印机信息，请联系售后技术支持人员核实',
        '1012' => '添加打印设备失败，请稍后再试或联系售后技术支持人员',
        '1013' => '打印订单时触发幂等性',
        '1014' => '幂等因子过长',
        '1016' => 'LOGO文件格式错误',
        '1017' => 'LOGO文件超出规定范围',
        '1018' => 'LOGO上传次数超限制',
        '1020' => 'LOGO删除失败',
        '1021' => 'LOGO上传模式错误',
        '1022' => '该设备属于定制设备，您当前无权使用',
    ];
    private $url = [
        'add' => "https://open.xpyun.net/api/openapi/xprinter/addPrinters", #添加打印机到开发者账户（可批量）
        'print' => "https://open.xpyun.net/api/openapi/xprinter/print", #打印小票订单
        'status' => "https://open.xpyun.net/api/openapi/xprinter/queryPrinterStatus", #获取指定打印机状态
        'del' => "https://open.xpyun.net/api/openapi/xprinter/delPrinters" #删除打印机
    ];
    private $platform_name = "优速外卖";

    public $sn = "74TRY38VJY5A148";
    public $name = "默认";
    public $order_id = 0;
    public $debug = 0;#1开始测试 0关闭
    public $copies = 1;#打印份数，默认为 1，最大值为 5，超出范围将视为无效参数
    public $order_type = 'order'; #order:订单 running跑腿  buy帮我买

    
     /**
     * 添加打印机
     */
    public function add(){
        $url = $this->url['add'];
        $time = $this->getMillisecond();
        $params = [
            'user' => $this->user,
            'timestamp' => $time,
            'sign' =>  sha1($this->user.$this->UserKey.$time),
            'debug' => 1,
            'items' => [[
                'name'=> "[{$this->platform_name}]".$this->name,
                'sn' => $this->sn
            ]]
        ];
    
        list($httpCode,$response) = $this->http_post_json($url,json_encode($params));
        if($httpCode == 200){
            if($response['code'] == 0  && !empty($response['data']['success'])){
                return self::code(0,'成功添加打印机');
            }else{
                try {
                    if(!empty($response['data']['failMsg'])){
                        $code = $response['data']['failMsg']['0'];
                        $code = explode(":",$code);
                        return self::code($code[1],$this->code_msg[$code[1]]);
                    }

                } catch (\Exception  $th) {
                    return self::code("-2","参数不合法".$th->getMessage());
                }
               
                return self::code($response['code'],"未知错误");
            }
        }else{
            return self::code('404','服务器请求失败');
        }
    }

     /**
     * 打印
     */
    public function print(){
        $url = $this->url['print'];
        $time = $this->getMillisecond();
        switch ($this->order_type) {
            case 'order':
                    $print_content = $this->OrderPrintContent();
                break;
            case 'buy':
                    $print_content = $this->BuyPrintContent();
                break;            
            case 'running':
                    $print_content = $this->RunningPrintContent();
                break;
            default:
                # code...
                break;
        }
        $params = [
            'user' => $this->user,
            'timestamp' => $time,
            'sign' =>  sha1($this->user.$this->UserKey.$time),
            'sn' => $this->sn,
            'content' => $print_content,
            'voice' => 2,
            'copies' => $this->copies,
        ];
        list($httpCode,$response) = $this->http_post_json($url,json_encode($params));
        if($httpCode == 200){
            if($response['code'] == 0){
                return self::code(0,'成功添加打印机');
            }
            return self::code($response['code'],$this->code_msg[$response['code']]);
        }else{
            return self::code('404','服务器请求失败');
        }
    }
    /**---
     *查询状态
    */
   public function status(){
       $url = $this->url['status'];
       $time = $this->getMillisecond();

       $params = [
           'user' => $this->user,
           'timestamp' => $time,
           'sign' =>  sha1($this->user.$this->UserKey.$time),
           'sn' => $this->sn,
       ];
       list($httpCode,$response) = $this->http_post_json($url,json_encode($params));
       if($httpCode == 200){

            switch ($response['data']) {
                case '0':
                    $msg = "离线";
                    break;
                case '1':
                    $msg = "在线正常";
                    break;
                case '2':
                    $msg = "在线异常";
                    break;
                default:
                    $msg = "检查打印机是否缺纸";
                    break;
            }
            return self::code($response['data'],$msg);
       }else{
           return self::code('404','服务器请求失败');
       }
   }
    /**
     * 删除打印机
     */
    public function delPrinters(){
       $url = $this->url['del'];
       $time = $this->getMillisecond();

       $params = [
           'user' => $this->user,
           'timestamp' => $time,
           'sign' =>  sha1($this->user.$this->UserKey.$time),
           'snlist' => [
                $this->sn
           ],
       ];
       list($httpCode,$response) = $this->http_post_json($url,json_encode($params));
       if($httpCode == 200){
           if($response['code'] == 0){
            return self::code($response['code'],"成功");
           }
           return self::code($response['code'],$this->code_msg[$response['code']]);
       }else{
           return self::code('404','服务器请求失败');
       }
    }
     /**
     * 打印模板订单-80
     */
    public function OrderPrintContent(){
        $order = (new \app\common\model\Orders())
        ->field([
            'id','type','order_on','user_id','money','pay_time','takeout_order_no','user_remarks',
            'start_address','end_address','phone','estimate_arrive_time','weather_money','urgent_status','urgent_price','store_id','money','total_money','username'
            ])
        ->append(['pay_time_text','type_text','user_text','goods_text','user_text','type_text','phone_encryption','estimate_arrive_time_text','store_name'])
        ->where(['id' => $this->order_id])
        ->hidden(['pay_time','type','user_id','phone'])
        ->find();
       
        if($this->debug == 1){
            $order = [
                'takeout_order_no' => '1',
                'store_name' => '测试商家名称',
                'type_text' => '普通订单',
                'order_on' => 'U202304121356196526',
                'goods_text' => [
                    ['goods_name' => '测试','numbers' => "1",'price' => "10.00",'goods_specs_name'=>'测试规格'],
                ],
                'urgent_status' => '1',
                'end_address' => '长春市朝阳区重庆路888号8单元802',
                'phone_encryption' => '1854****847',
                'phone' => '18549999847',
                'username' => '客户姓名',
                'pay_time_text' => date("Y-m-d H:i:s"),
                'user_remarks' => '少放辣 不吃香菜',
                'urgent_price' => '1.00',
                'weather_money' => '2.00',
                'money' => '12.00',
                'total_money' => '13.00',
           ];
        }


        $urgent_status = "";
        if($order['urgent_status'] == 1){
            $urgent_status = "<BOLD>(急)￥{$order['urgent_price']}</BOLD>";
        }
 
        $youhui = $order['total_money']-$order['money'];
        $youhui_html = "";
        if($youhui > 0){
            $youhui_html = "<R>优惠金额：".$youhui ."元<BR></R>";
        }
        $printContent = "";

        $printContent = $printContent . "<C>" . "<B>{$this->platform_name}</B>" . "<BR><BR></C>";
        $printContent = $printContent . "<C>" . "<B>#{$order['takeout_order_no']}{$order['store_name']}</B>" . "</C>";
        $printContent = $printContent . "<BR><C>{$order['type_text']}</C><BR>";
        $printContent = $printContent . "<BR><C>在线支付(已支付)</C><BR>";
        $printContent = $printContent . "<C>订单号：{$order['order_on']}</C><BR>";
        $printContent = $printContent . "<BR>";

        $printContent = $printContent . "菜名" . str_repeat(" ", 15) . "数量" . str_repeat(" ", 2) . "单价" . str_repeat(" ", 2)
            . "<BR>";
        $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
        foreach ($order['goods_text'] as $key => $value) {
            $printContent = $printContent . NoteFormatter::formatPrintOrderItem($value['goods_name']."-".$value['goods_specs_name'], $value['numbers'], $value['price']);
        }
        $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";

        $printContent = $printContent . $youhui_html ;
        // $printContent = $printContent . "{$urgent_status}<R>配送费：{$order['weather_money']}元<BR></R>" ;
        $printContent = $printContent . "<R>" . "合计：￥" . $order['money'] . "元" . "<BR></R>";

        $printContent = $printContent . "<BR>";
        $printContent = $printContent . "<L>"
            . "客户地址：" . $order['end_address']. "<BR>"
            . "客户姓名：" . $order['username'] . "<BR>"
            . "客户电话：" . $order['phone'] . "<BR>"
            . "下单时间：" . $order['pay_time_text'] . "<BR>";
        if(!empty($order['user_remarks'])){
            $printContent = $printContent . "备注：" . $order['user_remarks'] . "<BR>";
        }
          
       $printContent = $printContent . "<C>" . "<B>#{$order['takeout_order_no']}结束</B>" . "<BR></C>";
       return $printContent;
    }
    /**
     * 打印模板80-跑腿
     */
    public function RunningPrintContent(){
        $order = (new \app\common\model\RunningOrders())
        ->where(['id' => 106])
        ->field([
            'id','start_longitude','start_latitude','end_longitude','end_latitude','order_on',
            'start_address','end_address','take_phone','take_username','collect_phone','collect_username',
            'money','type','catty','picking_no','remarks','is_service','rider_status','order_status','picking_no','urgent_status'
            ])
        ->find();
       
        // if($this->debug == 1){
        //     $order = [
        //         'takeout_order_no' => '1',
        //         'store_name' => '测试商家名称',
        //         'type_text' => '普通订单',
        //         'order_on' => 'U202304121356196526',
        //         'goods_text' => [
        //             ['goods_name' => '测试','numbers' => "1",'price' => "10.00"],
        //         ],
        //         'urgent_status' => '1',
        //         'end_address' => '长春市朝阳区重庆路888号8单元802',
        //         'phone_encryption' => '1854****847',
        //         'phone' => '18549999847',
        //         'username' => '客户姓名',
        //         'pay_time_text' => date("Y-m-d H:i:s"),
        //         'user_remarks' => '少放辣 不吃香菜',
        //         'urgent_price' => '1.00',
        //         'weather_money' => '2.00',
        //         'money' => '12.00',
        //         'total_money' => '13.00',
        //    ];
        // }


        $urgent_status = "";
        if($order['urgent_status'] == 1){
            $urgent_status = "<BOLD>(急)￥{$order['urgent_price']}</BOLD>";
        }
 
     
        $printContent = "";

        $printContent = $printContent . "<C>" . "<B>{$this->platform_name}</B>" . "<BR><BR></C>";
        // $printContent = $printContent . "<C>" . "<B>#{$order['takeout_order_no']}{$order['store_name']}</B>" . "</C>";
        $printContent = $printContent . "<BR><C>{$order['type_text']}</C><BR>";
        $printContent = $printContent . "<BR><C>在线支付(已支付)</C><BR>";
        $printContent = $printContent . "<C>订单号：{$order['order_on']}</C><BR>";
        $printContent = $printContent . "<R>" . "合计：￥" . $order['money'] . "元" . "<BR></R>";
        $printContent = $printContent . "<BR>";
        switch ($order['type']) {
            case '0':
                $printContent = $printContent . "<L>" . "发货人：" . $order['take_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "发货人电话：" . $order['take_phone'] . "<BR>";

                $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
                $printContent = $printContent . "<L>" . "收件人：" . $order['collect_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "收件人电话：" . $order['collect_phone'] . "<BR>";

                $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
                $printContent = $printContent . "<L>" . "物品重量：" . $order['catty']."KG" . "<BR>";
                $printContent = $printContent . "<L>" . "取-地址：" . $order['start_address'] . "<BR>";
                $printContent = $printContent . "<L>" . "收-地址：" . $order['end_address'] . "<BR>";
            break;
            case '1':
                $printContent = $printContent . "<L>" . "发货人：" . $order['take_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "发货人电话：" . $order['take_phone'] . "<BR>";
                $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
                $printContent = $printContent . "<L>" . "收件人：" . $order['collect_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "收件人电话：" . $order['collect_phone'] . "<BR>";
                $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
                $printContent = $printContent . "<L>" . "物品重量：" . $order['catty']."KG" . "<BR>";

                $printContent = $printContent . "<L>" . "取-地址：" . $order['start_address'] . "<BR>";
                $printContent = $printContent . "<L>" . "收-地址：" . $order['end_address'] . "<BR>";
            break;
            case '2':
                $printContent = $printContent . "<L>" . "收货人：" . $order['collect_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "收件人电话：" . $order['collect_phone'] . "<BR>";
                $printContent = $printContent . "<L>" . "结束-地址：" . $order['end_address'] . "<BR>";
            break;
            case '3':
                $printContent = $printContent . "<L>" . "收货人：" . $order['collect_username'] . "<BR>";
                $printContent = $printContent . "<L>" . "收件人电话：" . $order['collect_phone'] . "<BR>";
                $printContent = $printContent . "<L>" . "取件码：" . $order['picking_no'] . "<BR>";
                $printContent = $printContent . "<L>" . "物品重量：" . $order['catty']."KG" . "<BR>";
                $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
                $printContent = $printContent . "<L>" . "取-地址：" . $order['start_address'] . "<BR>";
                $printContent = $printContent . "<L>" . "收-地址：" . $order['end_address'] . "<BR>";
            break;
            default:
                # code...
                break;
        }
     
    
        if(!empty($order['remarks'])){
            $printContent = $printContent . "备注：" . $order['user_remarks'] . "<BR>";
        }
          
       $printContent = $printContent . "<C>" . "<B>结束</B>" . "<BR></C>";
       return $printContent;
    }
     /**
     * 打印模板80-帮我买
     */
    public function BuyPrintContent(){
        $order = (new \app\common\model\Orders())
        ->field([
            'id','type','order_on','user_id','money','pay_time','takeout_order_no','user_remarks',
            'start_address','end_address','phone','estimate_arrive_time','weather_money','urgent_status','urgent_price','store_id','money','total_money','username'
            ])
        ->append(['pay_time_text','type_text','user_text','goods_text','user_text','type_text','phone_encryption','estimate_arrive_time_text','store_name'])
        ->where(['id' => $this->order_id])
        ->hidden(['pay_time','type','user_id','phone'])
        ->find();
  


        $urgent_status = "";
        if($order['urgent_status'] == 1){
            $urgent_status = "<BOLD>(急)￥{$order['urgent_price']}</BOLD>";
        }
 
        $youhui = $order['total_money']-$order['money'];
        $youhui_html = "";
        if($youhui > 0){
            $youhui_html = "<R>优惠金额：".$youhui ."元<BR></R>";
        }
        $printContent = "";

        $printContent = $printContent . "<C>" . "<B>{$this->platform_name}</B>" . "<BR><BR></C>";
        $printContent = $printContent . "<C>" . "<B>#{$order['takeout_order_no']}{$order['store_name']}</B>" . "</C>";
        $printContent = $printContent . "<BR><C>{$order['type_text']}</C><BR>";
        $printContent = $printContent . "<BR><C>在线支付(已支付)</C><BR>";
        $printContent = $printContent . "<C>订单号：{$order['order_on']}</C><BR>";
        $printContent = $printContent . "<BR>";

        $printContent = $printContent . "<L>" . "收货人：" . $order['collect_username'] . "<BR>";
        $printContent = $printContent . "<L>" . "收件人电话：" . $order['collect_phone'] . "<BR>";
        $printContent = $printContent . "<L>" . "取件码：" . $order['picking_no'] . "<BR>";
        $printContent = $printContent . "<L>" . "物品重量：" . $order['catty']."KG" . "<BR>";
        $printContent = $printContent . str_repeat("-", NoteFormatter::ROW_MAX_CHAR_LEN) . "<BR>";
        $printContent = $printContent . "<L>" . "取-地址：" . $order['start_address'] . "<BR>";
        $printContent = $printContent . "<L>" . "收-地址：" . $order['end_address'] . "<BR>";
        
        if(!empty($order['user_remarks'])){
            $printContent = $printContent . "备注：" . "少放辣 不吃香菜" . "<BR>";
        }
          
       $printContent = $printContent . "<C>" . "<B>#{$order['takeout_order_no']}结束</B>" . "<BR></C>";
       return $printContent;
    }
    
     /**
     * post请求封装
     */
    public function http_post_json($url, $jsonStr){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);// 发送一个常规的Post请求
        curl_setopt($ch, CURLOPT_URL, $url);// 要访问的地址
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json;charset=UTF-8',
                'Content-Length: ' . strlen($jsonStr)
            )
        );
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
       
        return array($httpCode,json_decode($response,true));
    }
    /**
     * 当前UNIX时间戳，精确到毫秒
     * @return string
     */
    public static function getMillisecond(){
        list($s1, $s2) = explode(' ', microtime());
        return sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
    }
    /**
     * 返回值封装
     */
    public static function code($code,$msg){
        $data = [
            'code' => $code,
            'msg' => $msg,
        ];
       return $data;
    }
}
